home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
9-Digit Zip Code Directory
/
9-Digit Zip Code Directory (American Business Information) (ABIZIP-12).ISO
/
z4src.zip
/
Z4Z5CP.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-09
|
6KB
|
188 lines
//----------------------------------------------------------------------------
// MODULE DESCRIPTION
//
// Module: z4z5cp.c
// Title: ZIP+4 Engine
// Notice: John M. Weeder
// Copyright (c) 1993. All rights reserved.
// This module contains proprietary information and should be
// treated as confidential.
//
//----------------------------------------------------------------------------
// MAINTENANCE HISTORY
//
// $Workfile$
// $Revision$
// $Author$
// $Date$
// $Log$
//
//----------------------------------------------------------------------------
// MODULE NARRATIVE
//
//
// This module contains the compressor for the ZIP5 file.
//
// The code in this module should be written entirely in C.
// Do not use any C++ constructs.
//
// This module is portable to:
// DOS 3.X+
// MS Windows 3.X+
// OS/2 2.X+
// OS/2 2.0 PM
// SCO UNIX.
//
// The following compilers are supported:
// MSC 6.0A
// MSC/C++ 7.0
// Borland C++ 3.1 for DOS
// Borland C++ 1.0 for OS/2 2.X
// SCO UNIX cc
//
//----------------------------------------------------------------------------
#include <z4.h>
//----------------------------------------------------------------------------
// Prototypes
//----------------------------------------------------------------------------
static BOOL FN_L Z4Z5CompressAppend(PDATACOMP, PZ4_Z5);
static RECID recid;
//----------------------------------------------------------------------------
// Description: Compression function
// Parameters: pdatacomp Compressor data
// Returns: Compression function result code. See data.h.
//----------------------------------------------------------------------------
SHORT FN_E Z4Z5Compress(PDATACOMP pdatacomp)
{
static BOOL fPending; // ZIP5 record pending?
static Z4_Z5 z5; // ZIP5 record
static LONG alZ5Count[Z4_ST_MAX];
static SIZET cMaxCities;
static SIZET cZip;
static SIZET cPof;
static SIZET cState;
LONG lRec = pdatacomp->dlmrec.lId;
PPSZ ppsz = pdatacomp->dlmrec.apsz;
Z4_STATE state;
switch (lRec)
{
case DAI_INITIALIZE: // Initialize at startup
memset(alZ5Count, 0, sizeof(alZ5Count));
cMaxCities = 0;
cZip = DataField(pdatacomp->dlmrec.pcfg, "zipcode");
cPof = DataField(pdatacomp->dlmrec.pcfg, "finance");
cState = DataField(pdatacomp->dlmrec.pcfg, "state_abbrev");
case DAI_START_BLK: // Start block
Assert(MAX_ZIP5_CITIES <= pdatacomp->cbMax / sizeof(RECID));
fPending = FALSE;
recid.usOffset = 0;
recid.lBlock = 0;
return DAO_SUCCESS;
case DAI_TERMINATE: // Terminate
if (!Z4Z5CountWrite(alZ5Count, sizeof(alZ5Count)))
return DAO_FAILURE;
Output("\nMaximum of %u city records in a 5 digit ZIP.\n", cMaxCities);
case DAI_FAILURE:
case DAI_END_BLK: // End block
return DAO_SUCCESS;
case DAI_LAST_REC:
if (!fPending)
return DAO_FAILURE;
Z4Z5CompressAppend(pdatacomp, &z5);
return DAO_FLUSH;
}
if (pdatacomp->dlmrec.fSkipped)
return DAO_SKIP;
if (fPending)
{
if (strcmp(z5.szZip5, ppsz[cZip]) != 0)
{
Z4Z5CompressAppend(pdatacomp, &z5);
fPending = FALSE;
return DAO_MARK_FLUSH;
}
Assert(z5.cCities < MAX_ZIP5_CITIES);
Assert(strcmp(z5.szFinance, ppsz[cPof]) == 0);
z5.arecid[z5.cCities] = pdatacomp->dlmrec.recid;
z5.cCities++;
cMaxCities = MAX(cMaxCities, z5.cCities);
return DAO_NEXT;
}
fPending = TRUE;
state = Z4FindState(ppsz[cState]);
alZ5Count[state]++;
memset(&z5, 0, sizeof(z5));
Assert(strcmp(ppsz[cZip], "00000") != 0);
strcpy(z5.szZip5, ppsz[cZip]);
strcpy(z5.szFinance, ppsz[cPof]);
z5.arecid[z5.cCities] = pdatacomp->dlmrec.recid;
z5.cCities++;
cMaxCities = MAX(cMaxCities, z5.cCities);
return DAO_NEXT;
}
//----------------------------------------------------------------------------
// Description: Compress the current ZIP5 record
// Parameters: pdatacomp Compresser data
// pz5 ZIP5 record
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
static BOOL FN_L Z4Z5CompressAppend(PDATACOMP pdatacomp, PZ4_Z5 pz5)
{
BYTE bBuf[sizeof(RECID) * MAX_ZIP5_CITIES];
SIZET cBuf;
PBYTE pb = pdatacomp->pb;
CHAR szZip5[MAX_ZIP5+2];
//
// Write the ZIP. The ZIP is stored as 6 characters, with the first
// character always being 9. This eliminates the problem of the first
// byte being zero and causing the expander to exit!
//
strcpy(szZip5, "9");
strcat(szZip5, pz5->szZip5);
stra2b(pb, MAX_ZIP5_BCD, szZip5, MAX_ZIP5+1);
pb += MAX_ZIP5_BCD;
// Finance number
stra2b(pb, MAX_FINANCE_BCD, pz5->szFinance, MAX_FINANCE);
pb += MAX_FINANCE_BCD;
// Encode record ids
if (!RecIdEncode(pz5->arecid, pz5->cCities, bBuf, sizeof(bBuf), &cBuf, &recid))
return FALSE;
Assert(cBuf); // Encode buffer size
cBuf--;
*pb = (BYTE)(cBuf & 0x007F);
if (cBuf > 0x007F)
{
*pb |= 0x80;
pb++;
Assert((cBuf >> 7) < 256);
*pb = (BYTE)cBuf;
pb++;
}
else
pb++;
cBuf++;
Assert(pdatacomp->cb <= pdatacomp->cbMax);
Assert(cBuf + 10 < pdatacomp->cbMax - pdatacomp->cb);
memcpy(pb, bBuf, cBuf); // Copy encoded record ids to output
pb += cBuf;
// Update number of bytes written
pdatacomp->cb = (SIZET)(pb - pdatacomp->pb);
return TRUE;
}
//----------------------------------------------------------------------------
//------------------------------- End of File --------------------------------
//----------------------------------------------------------------------------